package analysis;

import java.io.File;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import utils.Logger;
import visual.KMLPath;
import area.CityEvent;
import area.Placemark;

public class PresenceProbability {
	
	public static void main(String[] args) throws Exception {
		
		CityEvent event = CityEvent.GAME_SILVIO_PIOLA_11_3_2012;
		
		String dir = "D:/CODE/TELECOM/Telecom2/output/"+event.toString();
		File[] files = new File(dir).listFiles();
		
		KMLPath.openFile("output/"+event.toString()+"-PresenceProbability-UserTraces.kml");
		
		int count = 0;
		
		for(int i=0; i<files.length; i++) {
			File f = files[i];	
			if(!f.isFile()) continue;
			String filename = f.getName();
			String username = filename.substring(0, filename.indexOf(".csv"));
			List<PlsEvent> plsEvents = PlsEvent.readEvents(f);
			
			
			double p = presenceProbability(username,plsEvents,event);
			//Logger.logln(username.substring(0, 6)+" was attending with prob = "+p);
			
			if(p > 0.8) {
				count ++;
				KMLPath.print(username, plsEvents);
			}
		}
		
		Logger.logln("Estimated Attendance = "+count);
		KMLPath.closeFile();
		Logger.logln("Done!");
	}
	
	private static final DecimalFormat DF = new DecimalFormat("#.##",new DecimalFormatSymbols(Locale.US));
	
	
	
	public static double presenceProbability(String username, List<PlsEvent> plsEvents, CityEvent event) {
		double f1 = fractionOfTimeInWhichTheUserWasAtTheEvent(plsEvents,event);
		double f2 = fractionOfTimeInWhichTheUserIsUsuallyInTheEventArea(plsEvents,event);
		//Logger.logln(username+" = "+f1+", "+f2);
		return f1 * (1-f2);
	}
	
	
	public static double fractionOfTimeInWhichTheUserWasAtTheEvent(List<PlsEvent> plsEvents, CityEvent event) {
		Calendar first = null;
		Calendar last = null;
		boolean inEvent = false;
		for(PlsEvent pe: plsEvents) {			
			if(pe.getCalendar().after(event.st) && pe.getCalendar().before(event.et)) {
				//Logger.logln(">"+pe.getCalendar().getTime().toString());
				if(event.spot.contains(pe.getCellac())){
					if(inEvent==false) {
						//Logger.logln("The user enters the event!");
						inEvent = true;
					}
					first = (first == null || first.after(pe.getCalendar())) ? pe.getCalendar() : first;
					last = (last == null || last.before(pe.getCalendar())) ? pe.getCalendar() : last;
				}
				else if(inEvent) {
					//Logger.logln("The user walks away before the end!");
					inEvent = false;
				}
			}
			if(pe.getCalendar().after(event.et)) break;
			//else  Logger.logln(pe.getCalendar().getTime().toString());
		}
		
		if(first == null && last==null) return 0;	
		first.add(Calendar.MINUTE, -10);
		last.add(Calendar.MINUTE, 10);
		return 1.0 * (last.getTimeInMillis() - first.getTimeInMillis()) / (event.et.getTimeInMillis() - event.st.getTimeInMillis());
	}
	
	
	public static double fractionOfTimeInWhichTheUserIsUsuallyInTheEventArea(List<PlsEvent> plsEvents, CityEvent event) {
		
		Map<String,List<PlsEvent>> eventsPerDay = new HashMap<String,List<PlsEvent>>();
		
		for(PlsEvent pe: plsEvents) {	
			String k = pe.getCalendar().get(Calendar.DAY_OF_MONTH)+"-"+pe.getCalendar().get(Calendar.MONTH)+"-"+pe.getCalendar().get(Calendar.YEAR);
			List<PlsEvent> de = eventsPerDay.get(k);
			if(de == null) 
				de = new ArrayList<PlsEvent>();
			de.add(pe);
			eventsPerDay.put(k, de);
		}
		
		double f = 0;
		
		for(String k: eventsPerDay.keySet()) {
			String[] dmy = k.split("-");
			int day = Integer.parseInt(dmy[0]);
			int month = Integer.parseInt(dmy[1]);
			int year = Integer.parseInt(dmy[2]);
			CityEvent ce = event.changeDay(day, month, year);
			f += fractionOfTimeInWhichTheUserWasAtTheEvent(eventsPerDay.get(k),ce);
		}
		
		return f / eventsPerDay.size();
	}
	
}
